package ijeoma.tween;

class TweenEase {
	public float backEaseIn(float t, float b, float c, float d) {
		float s = 1.70158f;
		return c * (t /= d) * t * ((s + 1) * t - s) + b;
	}

	public float backEaseOut(float t, float b, float c, float d) {
		float s = 1.70158f;
		return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
	}

	public float backEaseBoth(float t, float b, float c, float d) {
		float s = 1.70158f;
		if ((t /= d / 2) < 1)
			return c / 2 * (t * t * (((s *= (1.525f)) + 1) * t - s)) + b;
		return c / 2 * ((t -= 2) * t * (((s *= (1.525f)) + 1) * t + s) + 2) + b;
	}

	public float bounceEaseIn(float t, float b, float c, float d) {
		return c - bounceEaseOut(d - t, 0, c, d) + b;
	}

	public float bounceEaseOut(float t, float b, float c, float d) {
		if ((t /= d) < (1 / 2.75f)) {
			return c * (7.5625f * t * t) + b;
		} else if (t < (2 / 2.75f)) {
			return c * (7.5625f * (t -= (1.5f / 2.75f)) * t + .75f) + b;
		} else if (t < (2.5 / 2.75)) {
			return c * (7.5625f * (t -= (2.25f / 2.75f)) * t + .9375f) + b;
		} else {
			return c * (7.5625f * (t -= (2.625f / 2.75f)) * t + .984375f) + b;
		}
	}

	public float bounceEaseBoth(float t, float b, float c, float d) {
		if (t < d / 2)
			return bounceEaseIn(t * 2, 0, c, d) * .5f + b;
		else
			return bounceEaseOut(t * 2 - d, 0, c, d) * .5f + c * .5f + b;
	}

	public float circEaseIn(float t, float b, float c, float d) {
		return -c * ((float) Math.sqrt(1 - (t /= d) * t) - 1) + b;
	}

	public float circEaseOut(float t, float b, float c, float d) {
		return c * (float) Math.sqrt(1 - (t = t / d - 1) * t) + b;
	}

	public float circEaseBoth(float t, float b, float c, float d) {
		if ((t /= d / 2) < 1)
			return -c / 2 * ((float) Math.sqrt(1 - t * t) - 1) + b;
		return c / 2 * ((float) Math.sqrt(1 - (t -= 2) * t) + 1) + b;
	}

	public float cubicEaseIn(float t, float b, float c, float d) {
		return c * (t /= d) * t * t + b;
	}

	public float cubicEaseOut(float t, float b, float c, float d) {
		return c * ((t = t / d - 1) * t * t + 1) + b;
	}

	public float cubicEaseBoth(float t, float b, float c, float d) {
		if ((t /= d / 2) < 1)
			return c / 2 * t * t * t + b;
		return c / 2 * ((t -= 2) * t * t + 2) + b;
	}

	public float elasticEaseIn(float t, float b, float c, float d) {
		if (t == 0)
			return b;
		if ((t /= d) == 1)
			return b + c;
		float p = d * .3f;
		float a = c;
		float s = p / 4;
		return -(a * (float) Math.pow(2, 10 * (t -= 1)) * (float) Math.sin((t * d - s) * (2 * (float) Math.PI) / p)) + b;
	}

	public float elasticEaseOut(float t, float b, float c, float d) {
		if (t == 0)
			return b;
		if ((t /= d) == 1)
			return b + c;
		float p = d * .3f;
		float a = c;
		float s = p / 4;
		return (a * (float) Math.pow(2, -10 * t) * (float) Math.sin((t * d - s) * (2 * (float) Math.PI) / p) + c + b);
	}

	public float elasticEaseBoth(float t, float b, float c, float d) {
		if (t == 0)
			return b;
		if ((t /= d / 2) == 2)
			return b + c;
		float p = d * (.3f * 1.5f);
		float a = c;
		float s = p / 4;
		if (t < 1)
			return -.5f * (a * (float) Math.pow(2, 10 * (t -= 1)) * (float) Math.sin((t * d - s) * (2 * (float) Math.PI) / p)) + b;
		return a * (float) Math.pow(2, -10 * (t -= 1)) * (float) Math.sin((t * d - s) * (2 * (float) Math.PI) / p) * .5f + c + b;
	}

	public float expoEaseIn(float t, float b, float c, float d) {
		return (t == 0) ? b : c * (float) Math.pow(2, 10 * (t / d - 1)) + b;
	}

	public float expoEaseOut(float t, float b, float c, float d) {
		return (t == d) ? b + c : c * (-(float) Math.pow(2, -10 * t / d) + 1) + b;
	}

	public float expoEaseBoth(float t, float b, float c, float d) {
		if (t == 0)
			return b;
		if (t == d)
			return b + c;
		if ((t /= d / 2) < 1)
			return c / 2 * (float) Math.pow(2, 10 * (t - 1)) + b;
		return c / 2 * (-(float) Math.pow(2, -10 * --t) + 2) + b;
	}

	public float linearEaseIn(float t, float b, float c, float d) {
		return c * t / d + b;
	}

	public float linearEaseOut(float t, float b, float c, float d) {
		return c * t / d + b;
	}

	public float linearEaseBoth(float t, float b, float c, float d) {
		return c * t / d + b;
	}

	public float quadEaseIn(float t, float b, float c, float d) {
		return c * (t /= d) * t + b;
	}

	public float quadEaseOut(float t, float b, float c, float d) {
		return -c * (t /= d) * (t - 2) + b;
	}

	public float quadEaseBoth(float t, float b, float c, float d) {
		if ((t /= d / 2) < 1)
			return c / 2 * t * t + b;
		return -c / 2 * ((--t) * (t - 2) - 1) + b;
	}

	public float quartEaseIn(float t, float b, float c, float d) {
		return c * (t /= d) * t * t * t + b;
	}

	public float quartEaseOut(float t, float b, float c, float d) {
		return -c * ((t = t / d - 1) * t * t * t - 1) + b;
	}

	public float quartEaseBoth(float t, float b, float c, float d) {
		if ((t /= d / 2) < 1)
			return c / 2 * t * t * t * t + b;
		return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
	}

	public float quintEaseIn(float t, float b, float c, float d) {
		return c * (t /= d) * t * t * t * t + b;
	}

	public float quintEaseOut(float t, float b, float c, float d) {
		return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
	}

	public float quintEaseBoth(float t, float b, float c, float d) {
		if ((t /= d / 2) < 1)
			return c / 2 * t * t * t * t * t + b;
		return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
	}

	public float sineEaseIn(float t, float b, float c, float d) {
		return -c * (float) Math.cos(t / d * (Math.PI / 2)) + c + b;
	}

	public float sineEaseOut(float t, float b, float c, float d) {
		return c * (float) Math.sin(t / d * (Math.PI / 2)) + b;
	}

	public float sineEaseBoth(float t, float b, float c, float d) {
		return -c / 2 * ((float) Math.cos(Math.PI * t / d) - 1) + b;
	}
}
